/**
 * 表单控件的控制类
 */
import { watch } from 'vue'
import createModel from './controllar/createModel'

import type {
  IAnyObject,
  IFromProps, // 表单控件需要的 meta
  IFormChildMetaList
} from '../main'

import { getColSpan } from './controllar/getColSpan'

// import createPartModel from './controllar/createPartModel'

import setControlShow from './controllar/setControlShow'

import {
  regFormState,
  getFormState
} from './state/stateForm'

/**
 * 表单控件的管理类
 * * 创建 v-model，创建局部 model，设置行列、排序相关的处理
 * @param formMeta 表单控件的 meta
 * @param model 表单的 model
 * @param partModel 表单的部分 model
 * @returns 
 */
export default function formController<T extends IAnyObject> (
  props: IFromProps<T>
) {

  // 
  
  const {
    formMeta, //: IFromMeta, 表单的 meta
    childPropsList, //: IFormItemList<T>, 表单子组件的 meta
    model, //: T, 表单的对象
    partModel, //?: any
  } = props
  
  // 注册一个状态，统一管理各种数据
  const state = regFormState(props)

  // 提取 表单子组件的 meta ，不要 props
  const childMetaList: IFormChildMetaList = {}
  Object.keys(childPropsList).forEach((key) => {
    childMetaList[key] = childPropsList[key].meta
  })

  // 表单里字段的排列顺序

  // 设置 model 的 属性
  const defauleModel = createModel(childPropsList, formMeta.colOrder)

  if (Object.keys(model).length < Object.keys(defauleModel).length) {
    // 没有属性或者属性不全，补全属性
    // const tmp = {}
    // Object.assign(tmp, defauleModel, model)
    // Object.assign(model, tmp)
    for (const key in defauleModel) {
      if (typeof model[key] === 'undefined') {
        model[key] = defauleModel[key]
      }
    }
  }

  // 关于一个字段占用几个td的问题
  const {
    formColSpan, // 一个字段占几个td的对象 
    setFormColSpan // 设置的函数
  } = getColSpan(formMeta.columnsNumber, childMetaList)

  // 监听列数，变化后重新设置
  watch(() => formMeta.columnsNumber, (num) => {
    setFormColSpan(num)
  }, { immediate:true })

  // 监听控件的格子数，变化后重置
  watch(childMetaList, (v1) => {
    setFormColSpan()
  })

  // 设置备选项和子控件的联动
  const {
    showCol,
    setFormColShow
  } = setControlShow(formMeta, childMetaList, model, partModel)

  // 监听联动的变化，更新
  watch(formMeta.linkageMeta, () => {
    setFormColShow()
  })

  watch(formMeta.colOrder, () => {
    setFormColShow()
    setFormColSpan()
  })

  // 返回重置函数 
  formMeta.reset = () => {
    // alert('表单内部修改外部函数')
    setFormColShow()
  }


  return {
    childMetaList,
    formColSpan, // 确定组件占位
    // formRules: rules, // 表单的验证规则
    showCol, // 是否显示字段的对象
    setFormColShow // 设置组件联动
  }
}
